#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MOD=147744151;
const int MAXN=1e3+5;
char buf[(1<<21)+5],*p1,*p2;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
int read(){
	int f=0,x=0;
	char ch=getchar();
	while(!isdigit(ch)){f|=(ch=='-');ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
	return f?-x:x;
}

int n,m,p,Q,ANS;
int a[MAXN][MAXN];
/*void test(){
	
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			int xans=1;
			for(int x=1;x<=i;x++)
				for(int y=1;y<=j;y++){
					xans*=a[x][y];
					xans%=p;
				}
					
			t[i][j]=xans;
		}
	for(int i=1;i<=n;i++,cout<<endl)
		for(int j=1;j<=m;j++)
			cout<<t[i][j]<<'\t';
}*/

struct segtree{
#define mid ((l+r)>>1)
#define ls ((x)<<1)
#define rs ((x)<<1|1)
	int tree[MAXN<<2];
	int Lv;
	void build(int x,int l,int r){
		if(l==r){
			tree[x]=a[Lv][l];
			return ;
		}
		build(ls,l,mid);
		build(rs,mid+1,r);
		tree[x]=tree[ls]*tree[rs]%p;
	}
	int q(int x,int l,int r,int L,int R){
		if(L<=l&&r<=R){
			return tree[x];
		}
		
		if(R<=mid)
		return q(ls,l,mid,L,R);
		else if(L>mid)
			return q(rs,mid+1,r,L,R);
		else 
			return q(ls,l,mid,L,mid)*q(rs,mid+1,r,mid+1,R)%p;
	}
}t[MAXN];
signed main(){
	freopen("tsuki.in","r",stdin);
	freopen("tsuki.out","w",stdout);
	n=read(),m=read(),p=read();
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++)
			a[i][j]=read();
	}
	for(int i=1;i<=n;i++){
		t[i].Lv=i;
		t[i].build(1,1,m);
	}
	//test();
	Q=read();
	for(int _i=1;_i<=Q;_i++){
		int X1,Y1,X2,Y2,ans=1;
		X1=read(),Y1=read(),X2=read(),Y2=read();
		for(int i=X1;i<=X2;i++){
			ans*=t[i].q(1,1,m,Y1,Y2);
			ans%=p;
		}
		ANS+=(_i^ans);
		ANS%=MOD;
	}
	cout<<ANS<<endl;
	return 0;
}
